﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using DiscoveryLogic.UI.Layouts.Converters;
using DiscoveryLogic.UI.Layouts.Models;
using DiscoveryLogic.UI.Layouts.Controls;
using DiscoveryLogic.UI.Layouts.DataAcccesses;
using DiscoveryLogic.DataServices.DataSources;

namespace DiscoveryLogic.UI.Layouts.ContentScreens
{
    public partial class FiveTwentyNineEnrollment : UserControl, IContentScreen
    {
        #region Private Variables

            MouseManager mouseEventManager;

            FundsManager fundsManager;

            int currentStep = 1;
            int[] currentTab = new int[5]{0, 0, 0, 0, 0};
            int lastStep = 5;

            List<Child> listOfChildren;

            List<PieChart> samplePieChartList;
            List<PieChart> allocationPieChartList;
            List<Enrollment529SavingsVis> visualizationList;

            List<EnrollmentFund> fundListFromWS;
            
        #endregion 

        #region Constructors

            public FiveTwentyNineEnrollment()
            {
                // Initialize variables
                InitializeComponent();

                fundsManager = new FundsManager();

                listOfChildren = new List<Child>();

                mouseEventManager = new MouseManager();

                // Get list of funds from WS
                fundListFromWS = fundsManager.GetFunds();

                samplePieChartList = new List<PieChart>();
                allocationPieChartList = new List<PieChart>();
                visualizationList = new List<Enrollment529SavingsVis>();

                // Add a single child application
                Child child = new Child();
                listOfChildren.Add(child);
                Enrollment529Form form = new Enrollment529Form();
                form.FullName = (string)this.Resources["Res_Child1Name"];
                form.Age = 12;
                form.CollegeSelection = Child.CollegeType.InState;
                ChildrenFormCanvas.Children.Add(form);

                // Create Step 2 Fund Legend
                CreateFundLegends(2);

                // Create Step 3 Fund Legend
                CreateFundLegends(3);

                // Attach handlers
                AttachEventHandlers();                
            }

        #endregion

        #region Helper Methods

            /// <summary>
            /// Look through a list of funds for a matching fund type.
            /// If found, return the name of the fund
            /// </summary>
            /// <param name="listOfFunds"></param>
            /// <param name="fundType"></param>
            /// <returns></returns>
            private string FindFundName(List<EnrollmentFund> listOfFunds, FundTypes fundType)
            {
                string name = fundType.ToString() + " Fund";

                if (listOfFunds != null)
                {
                    for (int i = 0; i < listOfFunds.Count; i++)
                    {
                        if (listOfFunds[i].FundType == fundType)
                        {
                            name = listOfFunds[i].FundName;
                            break;
                        }
                    }
                }

                return name;
            }

            private void CreateFundLegends(int step)
            {
                List<FundLegend> fundLegends = new List<FundLegend>();

                fundLegends.Add(new FundLegend(FundTypes.DomesticBonds, 50, 7));

                fundLegends.Add(new FundLegend(FundTypes.ForeignBonds, 50, 7));
                fundLegends[1].SetValue(Canvas.LeftProperty, 125.0);

                fundLegends.Add(new FundLegend(FundTypes.ShortTerm, 50, 7));
                fundLegends[2].SetValue(Canvas.LeftProperty, 250.0);

                fundLegends.Add(new FundLegend(FundTypes.DomesticEquity, 50, 7));
                fundLegends[3].SetValue(Canvas.TopProperty, 35.0);

                fundLegends.Add(new FundLegend(FundTypes.ForeignEquity, 50, 7));
                fundLegends[4].SetValue(Canvas.LeftProperty, 125.0);
                fundLegends[4].SetValue(Canvas.TopProperty, 35.0);

                fundLegends.Add(new FundLegend(FundTypes.Other, 50, 7));
                fundLegends[5].SetValue(Canvas.LeftProperty, 250.0);
                fundLegends[5].SetValue(Canvas.TopProperty, 35.0);

                for (int i = 0; i < 6; i++)
                {
                    if (step == 2)
                    {
                        Step2FundLegendCanvas.Children.Add(fundLegends[i]);
                    }
                    else if (step == 3)
                    {
                        Step3FundLegendCanvas.Children.Add(fundLegends[i]);
                    }
                }
            }

            /// <summary>
            /// Attach handlers to the elements in this scenario
            /// </summary>
            private void AttachEventHandlers()
            {
                // Attach handlers for mouse manager signaling a screen change
                mouseEventManager.changeStep += new MouseManager.NextStepEventHandler(OnNextScreen);

                // Attach handlers for Next button            
                NextButton.Click += new RoutedEventHandler(mouseEventManager.OnMouseClickNext);
                BackButton.Click += new RoutedEventHandler(mouseEventManager.OnMouseClickBack);
                FinishButton.Click += new RoutedEventHandler(OnMouseClickFinish);

                // Attach event handlers to media marker events for video in step 2
                Video529Encoded.MarkerReached += new TimelineMarkerRoutedEventHandler(Video529Encoded_MarkerReached);
            }
            

            private void ComputeNextSteps(int step)
            {
                bool created = false;
                double totalCollegeCost = 0;
                double totalMonthlyContribution = 0;

                for (int i = 0; i < listOfChildren.Count; i++)
                {
                    switch (step)
                    {
                        case 1:
                            // On Step 1 moving to Step 2
                            
                            // Capture children info
                            Enrollment529Form filledForm = (Enrollment529Form)ChildrenFormCanvas.Children[i];
                            listOfChildren[i].FullName = filledForm.FullName;
                            listOfChildren[i].InitialInvestment = filledForm.InitialInvestment;
                            listOfChildren[i].Age = filledForm.Age;
                            listOfChildren[i].AttendingCollegeType = filledForm.CollegeSelection;

                            // Create Tabs
                            CreateTabs(listOfChildren[i], i);
                            
                            // Create Sample Pie Charts
                            created = CreateSamplePieCharts(listOfChildren[i], i);

                            // Set text labels
                            Step2EstimatedCostLabel.Text = string.Format((string)this.Resources["Res_Step2EstimatedCost"], listOfChildren[currentTab[1]].CostOfCollege.ToCurrency());

                            TextBlock Step2Description = (TextBlock)Root.FindName("Step2DescriptionChild" + i);
                            TextBlock Step2Description2 = (TextBlock)Root.FindName("Step2Description2Child" + i);

                            Step2Description.Text = Step2Description.Text.Replace("[child" + i + "name]", listOfChildren[i].FirstName);
                            Step2Description2.Text = Step2Description2.Text.Replace("[child" + i + "name]", listOfChildren[i].FirstName);

                            break;
                        case 2:
                            // On Step 2 moving to Step 3

                            // Create Allocation Pie Charts
                            created = CreateAllocationPieCharts(listOfChildren[i], i);

                            // Create funds for fund panel
                            if (created)
                            { 
                                CreateSampleFunds(listOfChildren[i], i);
                            }

                            // Replace name in instructions text on the right side
                            Step3InstructionsText.Text = Step3InstructionsText.Text.Replace("[child"+i+"name]", listOfChildren[i].FirstName);
                            Step3InstructionsText2.Text = Step3InstructionsText2.Text.Replace("[child"+i+"name]", listOfChildren[i].FirstName);

                            break;
                        case 3:
                            // On Step 3 moving to Step 4

                            created = CreateSavingsVisualizations(listOfChildren[i], i);
                            
                            // If already created, then force it to redraw and recalculate
                            // monthly contribution because a child detail may have changed
                            if (created == false)
                            {
                                visualizationList[i].FocusOn();
                            }

                            break;
                        case 4:
                            // On Step 4 moving to Step 5
                            if (Step5Canvas0.Children.Count == 0)
                            {
                                Step5FullName.Text = listOfChildren[0].FullName;
                                Step5Age.Text = listOfChildren[0].Age.ToString();
                                Step5SchoolType.Text = listOfChildren[0].CollegeTypeString;
                                Step5CollegeCost.Text = listOfChildren[0].CostOfCollege.ToCurrency();
                                Step5InitialInvestment.Text = listOfChildren[0].InitialInvestment.ToCurrency();
                                Step5MonthlyContribution.Text = listOfChildren[0].MonthlyContribution.ToCurrency();                                
                                SummaryChartDescription0.Text = SummaryChartDescription0.Text.Replace("[child0name]", listOfChildren[0].FirstName);
                            }

                            CreateSummaryCharts(listOfChildren[i], i);

                            break;
                        default:
                            break;
                    }

                    totalCollegeCost += listOfChildren[i].CostOfCollege;
                    totalMonthlyContribution += listOfChildren[i].MonthlyContribution;
                }

                Step4TotalCollegeCostLabel.Text = Math.Round(totalCollegeCost).ToCurrency();
                Step4TotalMonthlyContribLabel.Text = Math.Round(totalMonthlyContribution).ToCurrency();

                Step5TotalCollege.Text =  Math.Round(totalCollegeCost).ToCurrency();
                Step5TotalMonthly.Text =  Math.Round(totalMonthlyContribution).ToCurrency();
            }

            /// <summary>
            /// Create a tab for this child in all steps
            /// </summary>
            /// <param name="c"></param>
            /// <param name="index"></param>
            private void CreateTabs(Child c, int index)
            {
                
                // We only have enough room for 3 tabs
                if (index >= 0 && index < 3)
                {
                    // Create tabs for all steps
                    for (int j = 2; j <= 5; j++)
                    {
                        Path tab = (Path)Root.FindName("Step"+j+"Tab" + index);
                        TextBlock label = (TextBlock)Root.FindName("Step"+j+"Tab" + index + "Name");
                        if (tab != null && label != null)
                        {
                            tab.Visibility = Visibility.Visible;
                            label.Text = c.FirstName;
                            label.Visibility = Visibility.Visible;
                        }
                    }
                }
            }

            /// <summary>
            /// Remove all tabs for this child
            /// </summary>
            /// <param name="c"></param>
            /// <param name="index"></param>
            private void RemoveTabs(int index)
            {                
                // Remove tabs for all steps
                for (int j = 2; j <= 5; j++)
                {
                    Path tab = (Path)Root.FindName("Step" + j + "Tab" + index);
                    TextBlock label = (TextBlock)Root.FindName("Step" + j + "Tab" + index + "Name");
                    if (tab != null && label != null)
                    {
                        tab.Visibility = Visibility.Collapsed;
                        label.Visibility = Visibility.Collapsed;
                    }
                }
                currentTab = new int[5]{0, 0, 0, 0, 0};
            }

            /// <summary>
            /// Create a sample pie chart for this child in step 2
            /// </summary>
            /// <param name="c"></param>
            /// <param name="index"></param>
            /// <returns>Returns true if created or false if already exists</returns>
            private bool CreateSamplePieCharts(Child c, int index)
            {
                // Check if we already have a sample pie chart at this index
                if (samplePieChartList.Count > index)
                {
                    return false;
                }

                // Create Sample pie chart in step 2
                PieChart samplePieChart = new PieChart(new Point(200, 200), 80, true, false);

                // Set properties                
                samplePieChart.AddSlice(0.25, 0.25, new EnrollmentFund(1, FundTypes.DomesticEquity, "Fund A", 0, 0.25));
                
                if (index == 0)
                {                    
                    samplePieChart.AddSlice(0.3, 0.3, new EnrollmentFund(12, FundTypes.ForeignBonds, "Fund Z", 0, 0.3));
                    samplePieChart.AddSlice(0.45, 0.45, new EnrollmentFund(6, FundTypes.DomesticBonds, "Fund G", 0, 0.45));
                }
                else if (index == 1)
                {
                    samplePieChart.AddSlice(0.15, 0.15, new EnrollmentFund(6, FundTypes.DomesticBonds, "Fund G", 0, 0.15));
                    samplePieChart.AddSlice(0.3, 0.3, new EnrollmentFund(12, FundTypes.ShortTerm, "Fund N", 0, 0.3));
                    samplePieChart.AddSlice(0.3, 0.3, new EnrollmentFund(11, FundTypes.ForeignEquity, "Fund K", 0, 0.3));
                }
                else if (index == 2)
                {
                    samplePieChart.AddSlice(0.25, 0.25, new EnrollmentFund(6, FundTypes.DomesticBonds, "Fund G", 0, 0.25));
                    samplePieChart.AddSlice(0.25, 0.25, new EnrollmentFund(12, FundTypes.ForeignBonds, "Fund N", 0, 0.25));
                    samplePieChart.AddSlice(0.25, 0.25, new EnrollmentFund(11, FundTypes.ForeignEquity, "Fund Z", 0, 0.25));
                }

                samplePieChart.HideFundValueLabels(true);
                samplePieChart.HideFundNameLabels(true);

                samplePieChart.DrawSlices();

                samplePieChart.SetValue(Canvas.NameProperty, "SamplePieChart" + index);

                // Add to canvas
                Canvas pieCanvas = (Canvas)Root.FindName("SamplePieCanvas" + index);
                pieCanvas.Children.Add(samplePieChart);

                // Add to list
                samplePieChartList.Add(samplePieChart);

                return true;
            }

            /// <summary>
            /// Create sample funds for the fund panel in step 3
            /// </summary>
            /// <param name="c"></param>
            /// <param name="index"></param>
            private void CreateSampleFunds(Child c, int index)
            {
                // Create funds
                List<EnrollmentFund> fundsList = fundsManager.GetFunds();


                for (int i = 0; i < fundsList.Count; i++)
                {
                    EnrollmentFund fundTab = fundsList[i];
                    Canvas FundPanel = (Canvas)Root.FindName("FundPanel" + index);
                    
                    // Set properties
                    fundTab.enrollmentFundDrag += new EventHandler(OnFundDrag);
                    fundTab.enrollmentFundMouseDown += new EventHandler(OnFundMouseDown);
                    fundTab.enrollmentFundMouseUp += new EventHandler(OnFundMouseUp);
                    fundTab.SetValue(Canvas.LeftProperty, 0.0);
                    fundTab.SetValue(Canvas.TopProperty, fundsList[i].Id * 40.0);
                    fundTab.SetValue(Canvas.ZIndexProperty, FundPanel.Children.Count);

                    // Add to canvas
                    FundPanel.Children.Add(fundTab);
                }

                // Create vertical slider
                Canvas fundSliderCanvas = (Canvas)Root.FindName("FundSlider" + index);
                VerticalSlider vs = new VerticalSlider();
                fundSliderCanvas.Children.Add(vs);
                vs.sliderMoved += new EventHandler(OnFundSliderMoved);
            }

            /// <summary>
            /// Create an allocation pie chart for this child in step 3
            /// </summary>
            /// <param name="c"></param>
            /// <param name="index"></param>
            /// <returns>returns true if created or false if already exists</returns>
            private bool CreateAllocationPieCharts(Child c, int index)
            {
                // If we already have an allocation pie chart for this child
                if (allocationPieChartList.Count > index)
                {
                    return false;
                }

                // Create allocation pie chart
                PieChart allocationPieChart = new PieChart(new Point(200, 200), 80);

                // Set properties                
                allocationPieChart.SetValue(Canvas.NameProperty, "AllocationPieChart" + index);

                // Set Slices              
                allocationPieChart.AddSlice(0.25, 0.25, new EnrollmentFund(1, FundTypes.DomesticEquity, FindFundName(fundListFromWS, FundTypes.DomesticEquity), 0, 0.25));

                if (index == 0)
                {
                    allocationPieChart.AddSlice(0.3, 0.3, new EnrollmentFund(12, FundTypes.ForeignBonds, FindFundName(fundListFromWS, FundTypes.ForeignBonds), 0, 0.3));
                    allocationPieChart.AddSlice(0.45, 0.45, new EnrollmentFund(6, FundTypes.DomesticBonds, FindFundName(fundListFromWS, FundTypes.DomesticBonds), 0, 0.45));
                }
                else if (index == 1)
                {
                    allocationPieChart.AddSlice(0.15, 0.15, new EnrollmentFund(6, FundTypes.DomesticBonds, FindFundName(fundListFromWS, FundTypes.DomesticBonds), 0, 0.15));
                    allocationPieChart.AddSlice(0.3, 0.3, new EnrollmentFund(12, FundTypes.ShortTerm, FindFundName(fundListFromWS, FundTypes.ShortTerm), 0, 0.3));
                    allocationPieChart.AddSlice(0.3, 0.3, new EnrollmentFund(11, FundTypes.ForeignEquity, FindFundName(fundListFromWS, FundTypes.ForeignEquity), 0, 0.3));
                }
                else if (index == 2)
                {
                    allocationPieChart.AddSlice(0.25, 0.25, new EnrollmentFund(6, FundTypes.DomesticBonds, FindFundName(fundListFromWS, FundTypes.DomesticBonds), 0, 0.25));
                    allocationPieChart.AddSlice(0.25, 0.25, new EnrollmentFund(12, FundTypes.ForeignBonds, FindFundName(fundListFromWS, FundTypes.ForeignBonds), 0, 0.25));
                    allocationPieChart.AddSlice(0.25, 0.25, new EnrollmentFund(11, FundTypes.ForeignEquity, FindFundName(fundListFromWS, FundTypes.ForeignEquity), 0, 0.25));
                }

                allocationPieChart.HideFundValueLabels(true);

                allocationPieChart.DrawSlices();

                allocationPieChart.IsAllocationChart = true;
                allocationPieChart.contributionChanged += new EventHandler(OnPieChartContributionChanged);
                allocationPieChart.contributionChanging += new EventHandler(OnPieChartContributionChanging);
                allocationPieChart.callAttachFund = AttachFund;

                // Check contribution allocation
                //CheckContributionAllocation(0);

                // Put in canvas
                Canvas currentPieCanvas = (Canvas)Root.FindName("AllocationPieCanvas" + index);
                currentPieCanvas.Children.Add(allocationPieChart);

                // Put in list
                allocationPieChartList.Add(allocationPieChart);

                return true;
            }

            /// <summary>
            /// Create savings visualizations for this child in step 4
            /// </summary>
            /// <param name="c"></param>
            /// <param name="index"></param>
            /// <returns>Returns true if created or false if already exists</returns>
            private bool CreateSavingsVisualizations(Child c, int index)
            {
                // Check if we already have a savings visualization for this child
                if (visualizationList.Count > index)
                {
                    return false;
                }

                // Find canvas
                Canvas chartCanvas = (Canvas)Root.FindName("Step4Canvas" + index);

                // Create visualization
                Enrollment529SavingsVis visualization;
                
                // Mocked up. If this is for second child,
                // growth is 10.5% due to riskier portfolio
                if (index == 1)
                {
                    visualization = new Enrollment529SavingsVis(c, 0.105);
                }
                else
                {
                    visualization = new Enrollment529SavingsVis(c, 0.06);
                }
                visualization.SetValue(Canvas.LeftProperty, 20.0);
                visualization.monthlyContributionChanged += new EventHandler(visualization_monthlyContributionChanged);

                // Add to canvas
                chartCanvas.Children.Add(visualization);

                // Add to list
                visualizationList.Insert(index, visualization);

                // Set focus
                visualization.FocusOn();

                return true;
            }

            /// <summary>
            /// Create summary pie charts for step 5
            /// </summary>
            /// <param name="c"></param>
            /// <param name="index"></param>
            private void CreateSummaryCharts(Child c, int index)
            {
                Canvas Step5Canvas = (Canvas)Root.FindName("Step5Canvas" + index);
                Step5Canvas.Children.Clear();

                // Create Sample pie chart in step 2
                PieChart summaryPieChart = new PieChart(new Point(35, 50), 35, true, false);

                // Set properties                
                List<PieSlice> sliceList = allocationPieChartList[index].GetPieSliceList();

                for (int i = 0; i < sliceList.Count; i++)
                {
                    summaryPieChart.AddSlice(sliceList[i].Fund.ContributionPercent, sliceList[i].Fund.ContributionPercent, new EnrollmentFund(sliceList[i].Fund.Id, sliceList[i].Fund.FundType, sliceList[i].Fund.FundName, 0, sliceList[i].Fund.ContributionPercent));
                }

                summaryPieChart.HideFundValueLabels(true);
                summaryPieChart.HideFundIcons(true);
                summaryPieChart.HideFundNameLabels(true);

                summaryPieChart.DrawSlices();

                summaryPieChart.SetValue(Canvas.NameProperty, "SummaryPieChart" + index);

                // Add to canvas                
                Step5Canvas.Children.Add(summaryPieChart);
            }
            
            /// <summary>
            /// Because setting visibility seems to cause crashes, this is a workaround
            /// </summary>
            /// <param name="btn"></param>
            /// <param name="visibility"></param>
            public void SetVisibleUsingWorkaround(Button btn, bool visibility)
            {
                if (visibility)
                {
                    btn.Opacity = 1.0;
                    btn.SetValue(Canvas.ZIndexProperty, 5);
                }
                else
                {
                    btn.Opacity = 0.0;
                    btn.SetValue(Canvas.ZIndexProperty, 0);
                }

            }

            /// <summary>
            /// This method changes the parent of a given fund from the fund panel
            /// to the pie chart panel while maintaining the same position on the screen.
            /// This is to facilitate dragging across containers.
            /// </summary>
            /// <param name="fund">The fund being dragged</param>
            private void FundPanelToPiePanel(EnrollmentFund fund, Canvas fromParent, Canvas toParent, MouseEventArgs e)
            {
                // Position of the fund
                double fundLeft = (double)fund.GetValue(Canvas.LeftProperty);
                double fundTop = (double)fund.GetValue(Canvas.TopProperty);

                // Distance from old parent and new parent
                Point fromPos = e.GetPosition(fromParent);
                Point toPos = e.GetPosition(toParent);

                // Differences
                Point deltaPos = new Point(fromPos.X - toPos.X, fromPos.Y - toPos.Y);
                Point newPos = new Point(fundLeft - deltaPos.X, fundTop - deltaPos.Y);

                // Set new values
                fund.SetValue(Canvas.LeftProperty, newPos.X);
                fund.SetValue(Canvas.TopProperty, newPos.Y);

                // Remove from old parent canvas
                fromParent.Children.Remove(fund);

                // Add to new parent canvas
                toParent.Children.Add(fund);
            }

            /// <summary>
            /// Attach a fund to the fund panel
            /// </summary>
            /// <param name="fund"></param>
            private void AttachFund(EnrollmentFund fund)
            {
                // Add fund to canvas
                Canvas FundPanel = (Canvas)Root.FindName("FundPanel" + currentTab[2]);
                FundPanel.Children.Add(fund);

                // Remove handlers if they exist because not sure which ones are there
                // and readd them
                fund.enrollmentFundDrag -= new EventHandler(OnFundDrag);
                fund.enrollmentFundMouseDown -= new EventHandler(OnFundMouseDown);
                fund.enrollmentFundMouseUp -= new EventHandler(OnFundMouseUp);

                fund.enrollmentFundDrag += new EventHandler(OnFundDrag);
                fund.enrollmentFundMouseDown += new EventHandler(OnFundMouseDown);
                fund.enrollmentFundMouseUp += new EventHandler(OnFundMouseUp);

                // Reset properties
                fund.ShrinkIcon();
                fund.SetValue(Canvas.LeftProperty, 0.0);
                fund.SetValue(Canvas.TopProperty, Convert.ToDouble(fund.Id * 40.0));
                fund.SetValue(Canvas.ZIndexProperty, fund.Id);
                fund.ResetPosition();
            }

            /// <summary>
            /// Make sure pie chart allocation is not over or under allocated
            /// </summary>
            /// <param name="offset"></param>
            private void CheckContributionAllocation(double offset)
            {
                PieChart allocationPieChart = allocationPieChartList[currentTab[2]];

                double percent = 1 - allocationPieChart.TotalContributionPercent + offset;

                if (percent != 0.0)
                {
                    ToAllocateExclamation.Opacity = 1;
                    ToAllocateExclamationText.Opacity = 1;
                    ToAllocateExclamationText.Text = AppResources.Get("Res_LeftToAllocate", percent.ToPercentage());
                }
                else
                {
                    ToAllocateExclamationText.Opacity = 0;
                    ToAllocateExclamation.Opacity = 0;
                }
            }
            
        #endregion

        #region Public Methods
        #endregion

        #region Event Handlers

            /// <summary>
            /// When the savings target or initial investment sliders are changed in step 4
            /// Savings Visualization, update the monthly contrib amount
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void visualization_monthlyContributionChanged(object sender, EventArgs e)
            {
                double totalMonthlyContrib = 0;

                // Calculate total
                for (int i = 0; i < listOfChildren.Count; i++)
                {
                    totalMonthlyContrib += listOfChildren[i].MonthlyContribution;
                }

                // Update label
                Step4TotalMonthlyContribLabel.Text = totalMonthlyContrib.ToCurrency();
            }

            /// <summary>
            /// When next or back is clicked
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void OnNextScreen(object sender, DiscoveryLogic.UI.Layouts.Models.CustomEventArgs e)
            {
                if (currentStep != 0 &&
                    (e.NextStep == true && NextButton.Opacity == 0 ||
                    e.NextStep == false && BackButton.Opacity == 0)
                    )
                {
                    return;
                }
          
                // Get current position of slider panel
                double leftPosition = (double)SlidePanel.GetValue(Canvas.LeftProperty);
                double previousStep = currentStep;

                // Determine which direction we are scrolling
                if (e.NextStep)
                {
                    ScrollSlidePanelKeyFrame.Value = leftPosition - 760;

                    // If first step, compute data for next steps based on form filled in step 1
                    ComputeNextSteps(currentStep);
                    
                    // Increment the variable that keeps track of what step we are in
                    currentStep++;

                    // Show elements which we hid because we didnt want them to 
                    // stick out onto other screens
                    switch(currentStep)
                    {
                        case 2:
                            Step2TabFrame.Opacity = 1;
                            Step2RightPanelCanvas.Opacity = 1;
                            break;
                        case 3:
                            // Stop step 2 video
                            if (Video529Encoded.CurrentState.Equals(MediaElementState.Playing))
                            {
                                Video529Encoded.Pause();
                            }
                            if (listOfChildren.Count < 2)
                            {
                                Step3InstructionsText2.Opacity = 0;
                            }
                            else
                            {
                                Step3InstructionsText2.Opacity = 1;
                            }
                            Step2RightPanelCanvas.Opacity = 0;
                            Step4TabFrame.Opacity = 0;
                            break;
                        case 4:
                            Step4TabFrame.Opacity = 1;
                            Step5TabFrame.Opacity = 0;
                            break;
                        case 5:
                            Step5TabFrame.Opacity = 1;
                            break;
                        default:
                            break;
                    }                    
                }
                else
                {                    
                    // Decrement the variable that keeps track of what step we are in
                    currentStep--;

                    // Ensure edges of other steps don't stick out onto the current screen
                    switch (currentStep)
                    {
                        case 0:
                            // Step 0 is supposed to bring us to the 
                            // new account menu in the enrollment scenario
                            if (backToNewAccountMenu != null)
                            {
                                backToNewAccountMenu(this, new EventArgs());
                            }
                            currentStep = 1;
                            return;
                            
                        case 1:
                            // Stop step 2 video
                            if (Video529Encoded.CurrentState.Equals(MediaElementState.Playing))
                            {
                                Video529Encoded.Pause();
                            }
                            Step2TabFrame.Opacity = 0;
                            break;
                        case 2:
                            Step2RightPanelCanvas.Opacity = 1;                            
                            break;
                        case 3:
                            break;
                        case 4:
                            Step4TabFrame.Opacity = 1;
                            break;
                        default:
                            break;
                    }

                    ScrollSlidePanelKeyFrame.Value = leftPosition + 760;                    
                }

                // Change opacity of previous Step label
                TextBlock tb = (TextBlock)Root.FindName("Step" + previousStep + "Label");
                if (tb != null)
                {
                    tb.Opacity = 0.3;
                }

                // Change opacity of current Step label
                tb = (TextBlock)Root.FindName("Step" + currentStep + "Label");
                if (tb != null)
                {
                    tb.Opacity = 1;
                }
              
                // Hide buttons
                //NextButton.Visibility = Visibility.Collapsed;
                //BackButton.Visibility = Visibility.Collapsed;
                //FinishButton.Visibility = Visibility.Collapsed;

                SetVisibleUsingWorkaround(NextButton, false);
                SetVisibleUsingWorkaround(BackButton, false);
                SetVisibleUsingWorkaround(FinishButton, false);

                // Start scroll animation
                ScrollSlidePanel.Begin();
            }

            private void OnMouseClickFinish(object sender, RoutedEventArgs e)
            {
                // If finish button is invisible when the user clicks it,
                // don't show it.
                if (FinishButton.Opacity == 0)
                {
                    return;
                }

                if (fiveTwentyNineEnrollmentComplete != null)
                {
                    SetVisibleUsingWorkaround(FinishButton, false);
                    SetVisibleUsingWorkaround(BackButton, false);
                    fiveTwentyNineEnrollmentComplete(this, new EventArgs());
                }
            }

            /// <summary>
            /// When the scrolling animation for the screen stops
            /// this method is fired. This method sets the visibility
            /// of the back/next/finished buttons
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void OnScrollComplete(object sender, EventArgs e)
            {
                // If last step, make "Next" button invisible
                if (currentStep == lastStep)
                {
                    //NextButton.Visibility = Visibility.Collapsed;
                    FinishButton.Visibility = Visibility.Visible;

                    SetVisibleUsingWorkaround(NextButton, false);
                    SetVisibleUsingWorkaround(FinishButton, true);
                }
                else if (currentStep != 0)
                {
                    NextButton.Visibility = Visibility.Visible;
                    SetVisibleUsingWorkaround(NextButton, true);
                    //   FinishButton.Visibility = Visibility.Collapsed;
                    SetVisibleUsingWorkaround(FinishButton, false);
                }

                // If not first step, then make "Previous" button visible
                if (currentStep != 0)
                {
                    BackButton.Visibility = Visibility.Visible;
                    SetVisibleUsingWorkaround(BackButton, true);
                }
                else
                {
                    // BackButton.Visibility = Visibility.Collapsed;
                    SetVisibleUsingWorkaround(BackButton, false);
                }
            }

            /// <summary>
            /// Text box that specifies the number of children we're planning 
            /// for has changed.
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void NumberOfChildren_TextChanged(object sender, TextChangedEventArgs e)
            {
                int numOfChildren;

                // If blank, then return
                if (NumberOfChildren.Text == "")
                {
                    return;
                }
                
                // Retrieve number of children specified
                try
                {
                    // TODO: Exception will be thrown if non-numeric char in text
                    numOfChildren = Convert.ToInt16(NumberOfChildren.Text);
                }
                catch  
                {
                    return;
                }

                // Ensure at least one child
                if (numOfChildren <= 0)
                {
                    numOfChildren = 1;
                    NumberOfChildren.Text = "1";
                }
                else if (numOfChildren > 3)
                {
                    // Limit amount of children to 3 for demo purposes
                    numOfChildren = 3;
                    NumberOfChildren.Text = "3";
                }
                
                while(numOfChildren != listOfChildren.Count)
                {
                    if (numOfChildren > listOfChildren.Count)
                    {
                        Child child = new Child();
                        listOfChildren.Add(child);

                        Enrollment529Form form = new Enrollment529Form();

                        // Mocked up
                        if (listOfChildren.Count == 2)
                        {
                            // second child
                            form.FullName = (string)this.Resources["Res_Child2Name"];
                            form.Age = 7;
                            form.CollegeSelection = Child.CollegeType.Private;
                        }
                        else if (listOfChildren.Count == 3)
                        {
                            // third child
                            form.FullName = (string)this.Resources["Res_Child3Name"];
                            form.Age = 10;
                            form.CollegeSelection = Child.CollegeType.OutOfState;
                        }

                        ChildrenFormCanvas.Children.Add(form);
                    }
                    else
                    {
                        // Remove last child
                        RemoveTabs(listOfChildren.Count - 1);
                        listOfChildren.RemoveAt(listOfChildren.Count - 1);
                        // Remove last children application form from the canvas
                        ChildrenFormCanvas.Children.RemoveAt(ChildrenFormCanvas.Children.Count - 1);
                    }
                }
            }

            /// <summary>
            /// 
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void OnStep2Tabs_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
            {
                // Turn all off
                ToggleStep2Tab(0, false);
                ToggleStep2Tab(1, false);
                ToggleStep2Tab(2, false);

                // Set tab that was clicked to be on
                if (sender == Step2Tab0 || sender == Step2Tab0Name)
                {
                    currentTab[1] = 0;
                }
                else if (sender == Step2Tab1 || sender == Step2Tab1Name)
                {
                    currentTab[1] = 1;                    
                }
                else if (sender == Step2Tab2 || sender == Step2Tab2Name)
                {
                    currentTab[1] = 2;
                }

                ToggleStep2Tab(currentTab[1], true);
            }

            private void ToggleStep2Tab(int index, bool show)
            {
                Canvas SamplePieCanvas = (Canvas)Root.FindName("SamplePieCanvas" + index);
                Path Step2Tab = (Path)Root.FindName("Step2Tab" + index);
                TextBlock Step2Description = (TextBlock)Root.FindName("Step2DescriptionChild" + index);
                TextBlock Step2Description2 = (TextBlock)Root.FindName("Step2Description2Child" + index);

                if (show)
                {
                    //SamplePieCanvas.Visibility = Visibility.Visible;
                    SamplePieCanvas.Opacity = 1;
                    // Don't show if video frame is visible
                    if (VideoFrame.Opacity == 0)
                    {
                        Step2Description.Opacity = 1;
                    }
                    Step2Description2.Opacity = 1;
                    Step2Tab.SetValue(Canvas.ZIndexProperty, 2);
                    Step2Tab.Fill = new SolidColorBrush(Colors.White);
                    Step2EstimatedCostLabel.Text = string.Format((string)this.Resources["Res_Step2EstimatedCost"], listOfChildren[currentTab[1]].CostOfCollege.ToCurrency());
                    currentTab[1] = index;
                }
                else
                {
                    //SamplePieCanvas.Visibility = Visibility.Collapsed;
                    SamplePieCanvas.Opacity = 0;
                    Step2Description.Opacity = 0;
                    Step2Description2.Opacity = 0;
                    Step2Tab.SetValue(Canvas.ZIndexProperty, 0);
                    Step2Tab.Fill = new SolidColorBrush(Utils.HexToColor("#55012F2F"));
                }                
            }

            /// <summary>
            /// 
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void OnStep3Tabs_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
            {
                // Turn all off
                ToggleStep3Tab(0, false);
                ToggleStep3Tab(1, false);
                ToggleStep3Tab(2, false);

                // Set tab that was clicked to be on
                if (sender == Step3Tab0 || sender == Step3Tab0Name)
                {
                    currentTab[2] = 0;
                }
                else if (sender == Step3Tab1 || sender == Step3Tab1Name)
                {
                    currentTab[2] = 1;
                }
                else if (sender == Step3Tab2 || sender == Step3Tab2Name)
                {
                    currentTab[2] = 2;
                }

                ToggleStep3Tab(currentTab[2], true);
            }

            private void ToggleStep3Tab(int index, bool show)
            {
                Canvas AllocationPieCanvas = (Canvas)Root.FindName("AllocationPieCanvas" + index);
                Canvas FundList = (Canvas)Root.FindName("FundList" + index);
                Canvas FundSlider = (Canvas)Root.FindName("FundSlider" + index);
                Path Step3Tab = (Path)Root.FindName("Step3Tab" + index);

                if (show)
                {
                    //AllocationPieCanvas.Visibility = Visibility.Visible;
                    AllocationPieCanvas.Opacity = 1;
                    AllocationPieCanvas.SetValue(Canvas.ZIndexProperty, 2);
                    FundList.Visibility = Visibility.Visible;
                    FundSlider.Visibility = Visibility.Visible;
                    Step3Tab.SetValue(Canvas.ZIndexProperty, 2);
                    Step3Tab.Fill = new SolidColorBrush(Colors.White);
                    CheckContributionAllocation(0);
                }
                else
                {
                    //AllocationPieCanvas.Visibility = Visibility.Collapsed;
                    AllocationPieCanvas.Opacity = 0;
                    AllocationPieCanvas.SetValue(Canvas.ZIndexProperty, 0);
                    FundList.Visibility = Visibility.Collapsed;
                    FundSlider.Visibility = Visibility.Collapsed;
                    Step3Tab.SetValue(Canvas.ZIndexProperty, 0);
                    Step3Tab.Fill = new SolidColorBrush(Utils.HexToColor("#55012F2F"));
                }
            }

            /// <summary>
            /// 
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void OnStep4Tabs_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
            {
                // Turn all off
                ToggleStep4Tab(0, false);
                ToggleStep4Tab(1, false);
                ToggleStep4Tab(2, false);

                // Set tab that was clicked to be on
                if (sender == Step4Tab0 || sender == Step4Tab0Name)
                {
                    currentTab[3] = 0;
                }
                else if (sender == Step4Tab1 || sender == Step4Tab1Name)
                {
                    currentTab[3] = 1;
                }
                else if (sender == Step4Tab2 || sender == Step4Tab2Name)
                {
                    currentTab[3] = 2;
                }

                ToggleStep4Tab(currentTab[3], true);
            }

            private void ToggleStep4Tab(int index, bool show)
            {
                Canvas Step4Canvas = (Canvas)Root.FindName("Step4Canvas" + index);
                Path Step4Tab = (Path)Root.FindName("Step4Tab" + index);

                if (show)
                {
                    Step4Canvas.Visibility = Visibility.Visible;
                    Step4Tab.SetValue(Canvas.ZIndexProperty, 2);
                    Step4Tab.Fill = new SolidColorBrush(Colors.White);
                    visualizationList[index].FocusOn();
                    
                }
                else
                {
                    Step4Canvas.Visibility = Visibility.Collapsed;
                    Step4Tab.SetValue(Canvas.ZIndexProperty, 0);
                    Step4Tab.Fill = new SolidColorBrush(Utils.HexToColor("#55012F2F"));
                }
            }

            /// <summary>
            /// 
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void OnStep5Tabs_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
            {
                // Turn all off
                ToggleStep5Tab(0, false);
                ToggleStep5Tab(1, false);
                ToggleStep5Tab(2, false);

                // Set tab that was clicked to be on
                if (sender == Step5Tab0 || sender == Step5Tab0Name)
                {
                    currentTab[4] = 0;
                }
                else if (sender == Step5Tab1 || sender == Step5Tab1Name)
                {
                    currentTab[4] = 1;
                }
                else if (sender == Step5Tab2 || sender == Step5Tab2Name)
                {
                    currentTab[4] = 2;
                }

                ToggleStep5Tab(currentTab[4], true);
            }

            private void ToggleStep5Tab(int index, bool show)
            {
                Canvas Step5Canvas = (Canvas)Root.FindName("Step5Canvas" + index);
                Path Step5Tab = (Path)Root.FindName("Step5Tab" + index);
                TextBlock SummaryChartDescription = (TextBlock)Root.FindName("SummaryChartDescription" + index);

                if (show)
                {
                    //Step5Canvas.Visibility = Visibility.Visible;
                    Step5Canvas.Opacity = 1;
                    Step5FullName.Text = listOfChildren[index].FullName;
                    Step5Age.Text = listOfChildren[index].Age.ToString();
                    Step5SchoolType.Text = listOfChildren[index].CollegeTypeString;
                    Step5CollegeCost.Text = listOfChildren[index].CostOfCollege.ToCurrency();
                    Step5InitialInvestment.Text = listOfChildren[index].InitialInvestment.ToCurrency();
                    Step5MonthlyContribution.Text = listOfChildren[index].MonthlyContribution.ToCurrency();
                    SummaryChartDescription.Text = SummaryChartDescription.Text.Replace("[child" + index + "name]", listOfChildren[index].FirstName);
                    SummaryChartDescription.Opacity = 1;

                    Step5Tab.SetValue(Canvas.ZIndexProperty, 2);
                    Step5Tab.Fill = new SolidColorBrush(Colors.White);
                }
                else
                {
                    //Step5Canvas.Visibility = Visibility.Collapsed;
                    Step5Canvas.Opacity = 0;
                    SummaryChartDescription.Opacity = 0;
                    Step5Tab.SetValue(Canvas.ZIndexProperty, 0);
                    Step5Tab.Fill = new SolidColorBrush(Utils.HexToColor("#55012F2F"));
                }
            }

            /// <summary>
            /// As the fund is being dragged, check if its
            /// over a pie slice. If so, highlight the slice.
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void OnFundDrag(object sender, EventArgs e)
            {
                MouseEventArgs args = (MouseEventArgs)e;
                EnrollmentFund fund = (EnrollmentFund)sender;
                // Check if it overlaps pie slices
                PieChart pc = Root.FindName("AllocationPieChart" + currentTab[2]) as PieChart;
                bool hit = pc.HitTestHighlight(args);
            }

            /// <summary>
            /// When the user clicks a fund, change the funds
            /// parent from the fund panel to the enrollment canvas.
            /// This is to make it have the highest z index.
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void OnFundMouseDown(object sender, EventArgs e)
            {
                MouseEventArgs args = (MouseEventArgs)e;
                EnrollmentFund fund = (EnrollmentFund)sender;
                Canvas fromCanvas = (Canvas)Root.FindName("FundPanel" + currentTab[2]);
                Canvas toCanvas = (Canvas)Root.FindName("AllocationPieCanvas" + currentTab[2]);
                FundPanelToPiePanel(fund, fromCanvas, toCanvas, args);
            }

            /// <summary>
            /// When the user releases a fund, check if it is over a pie slice.
            /// If not, move it back to fund panel
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void OnFundMouseUp(object sender, EventArgs e)
            {
                MouseEventArgs args = (MouseEventArgs)e;
                EnrollmentFund fund = (EnrollmentFund)sender;

                Canvas currentPieCanvas = (Canvas)Root.FindName("AllocationPieCanvas" + currentTab[2]);
                Canvas currentFundPanelCanvas = (Canvas)Root.FindName("FundPanel" + currentTab[2]);

                // Test if we're adding this fund
                PieChart pc = Root.FindName("AllocationPieChart" + currentTab[2]) as PieChart;
                bool hit = pc.HitTestHighlight(args);

                if (hit == true)
                {
                    fund.SetValue(Canvas.LeftProperty, 0.0);
                    fund.SetValue(Canvas.TopProperty, 0.0);

                    if (currentPieCanvas.Children.Contains(fund))
                    {
                        currentPieCanvas.Children.Remove(fund);
                        pc.AddFund(fund);
                    }
                }
                else
                {                    
                    // Move fund from enrollment canvas back to fund list canvas
                    if (currentPieCanvas.Children.Contains(fund))
                    {
                        currentPieCanvas.Children.Remove(fund);

                        // FIXED: Periodically a value out of range exception is thrown.
                        currentFundPanelCanvas.Children.Add(fund);
                        fund.SetValue(Canvas.LeftProperty, 0.0);
                        fund.SetValue(Canvas.TopProperty, Convert.ToDouble(fund.Id * 40));
                        fund.ResetPosition();
                    }                    
                }
            }

            /// <summary>
            /// When the fund panel slider is moved, move the canvas
            /// that the funds are on.
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void OnFundSliderMoved(object sender, EventArgs e)
            {                
                VerticalSlider vs = (VerticalSlider)sender;
                double lowestFundPosition = 0;

                // Find current fund panel according to which tab we're looking at
                Canvas FundPanel = (Canvas)Root.FindName("FundPanel" + currentTab[2]);

                // If there are children, find the lowest fund position
                for (int i = 0; i < FundPanel.Children.Count; i++)
                {
                    if ((double)FundPanel.Children[i].GetValue(Canvas.TopProperty) > lowestFundPosition)
                    {
                        lowestFundPosition = (double)FundPanel.Children[i].GetValue(Canvas.TopProperty);
                    }
                }

                // The min is the top of the canvas
                double fundPanelMin = 5;

                // The max is the lowest fund - the viewable area which is 4 funds
                // each fund is 40, so its maxID + 1 * 40 to get the max lenght then 
                // minus the viewable area which is 4 * 40.
                double fundPanelMax = (lowestFundPosition + 40) - (4 * 40);
                double distance = fundPanelMin - ((fundPanelMax - fundPanelMin) * vs.GetPercentage());

                FundPanel.SetValue(Canvas.TopProperty, distance);

            }

            /// <summary>
            /// When the contribution for a pie slice has changed,
            /// update the "%% Left to allocate" label
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void OnPieChartContributionChanged(object sender, EventArgs e)
            {
                CheckContributionAllocation(0);
            }

            private void OnPieChartContributionChanging(object sender, EventArgs e)
            {
                DiscoveryLogic.UI.Layouts.Models.CustomEventArgs args = (DiscoveryLogic.UI.Layouts.Models.CustomEventArgs)e;

                CheckContributionAllocation(args.ContributionOffset);
            }

            /// <summary>
            /// On play video button click in step 2. 
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void PlayBut_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
            {
                if (VideoFrame.Opacity == 0)
                {
                    ShowVideoPlayer.Begin();
                }
                else if (Video529Encoded.CurrentState.Equals(MediaElementState.Playing))
                {
                    Video529Encoded.Pause();
                }               
                else
                {
                    Video529Encoded.Play();
                }
               
            }

        #endregion

        #region Events

            public event EventHandler fiveTwentyNineEnrollmentComplete;

            public event EventHandler backToNewAccountMenu;
            
        #endregion

        #region IContentScreen Members

            public void ScreenShowActions()
            {
                SetVisibleUsingWorkaround(BackButton, true);
                SetVisibleUsingWorkaround(NextButton, true);
            }

            public void ScreenHideActions()
            {
                double leftPosition = (double)SlidePanel.GetValue(Canvas.LeftProperty);
                SlidePanel.SetValue(Canvas.LeftProperty, 100.197);

                // Hide buttons
                SetVisibleUsingWorkaround(BackButton, false);
                SetVisibleUsingWorkaround(FinishButton, false);
                SetVisibleUsingWorkaround(NextButton, false);

                // Change opacity of previous Step indicator label
                TextBlock tb = (TextBlock)Root.FindName("Step" + currentStep + "Label");
                if (tb != null)
                {
                    tb.Opacity = 0.3;
                }

                // Set step 1 label to be highlighted
                tb = (TextBlock)Root.FindName("Step1Label");
                if (tb != null)
                {
                    tb.Opacity = 1;
                }

                currentStep = 1;

                // Stop video in step 2
                if (Video529Encoded.CurrentState.Equals(MediaElementState.Playing))
                {
                    Video529Encoded.Pause();
                }
            
            }

        #endregion

            private void ShowVideoPlayer_Completed(object sender, EventArgs e)
            {
                
                    Video529Encoded.Play();
                
            }

            /// <summary>
            /// Video in step 2 media marker reached
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Video529Encoded_MarkerReached(object sender, TimelineMarkerRoutedEventArgs e)
            {
                PieChart samplePieChart = samplePieChartList[currentTab[1]];

                List<PieSlice> pieList = samplePieChart.GetPieSliceList();

                switch (e.Marker.Text)
                {
                    case "PortfolioIn":
                        foreach (PieSlice slice in pieList)
                        {
                            slice.LiftSlice();
                        }
                        break;
                    case "PortfolioOut":
                        foreach (PieSlice slice in pieList)
                        {
                            slice.LowerSlice();
                        }
                        break;
                    case "NextIn":
                        NextButton.Width = 100;
                        NextButton.Height = 65;
                        break;
                    case "NextOut":
                        NextButton.Width = 96.5;
                        NextButton.Height = 60;
                        break;                    
                    default:
                        break;
                }
            }

    }
}
